package datastruct

import "sync"

type LinkStack struct {
	Root *StackNode //
	Size int        `json:"Size"`
	lock sync.Mutex
}
type StackNode struct {
	Next  *StackNode
	Value string
}

// 入栈
func (stack *LinkStack) Push(v string) {
	stack.lock.Lock()
	defer stack.lock.Unlock()

	// 如果栈顶为空，那么增加节点
	if stack.Root == nil {
		stack.Root = new(StackNode)
		stack.Root.Value = v
	} else {
		// 否则新元素插入链表的头部
		// 原来的链表
		preNode := stack.Root

		// 新节点
		newNode := new(StackNode)
		newNode.Value = v

		// 原来的链表链接到新元素后面
		newNode.Next = preNode

		// 将新节点放在头部
		stack.Root = newNode
	}

	// 栈中元素数量+1
	stack.Size = stack.Size + 1
}

// 出栈
func (stack *LinkStack) Pop() string {
	stack.lock.Lock()
	defer stack.lock.Unlock()

	// 栈中元素已空
	if stack.Size == 0 {
		panic("empty")
	}

	// 顶部元素要出栈
	topNode := stack.Root
	v := topNode.Value

	// 将顶部元素的后继链接链上
	stack.Root = topNode.Next

	// 栈中元素数量-1
	stack.Size = stack.Size - 1

	return v
}

// 获取栈顶元素
func (stack *LinkStack) Peek() string {
	// 栈中元素已空
	if stack.Size == 0 {
		panic("empty")
	}

	// 顶部元素值
	v := stack.Root.Value
	return v
}

// 栈大小
func (stack *LinkStack) StackSize() int {
	return stack.Size
}

// 栈是否为空
func (stack *LinkStack) IsEmpty() bool {
	return stack.Size == 0
}
